﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using Warensoft.Unity.Communication.Client;
namespace Warensoft.Unity.Communication.Client.DbClient
{
    /// <summary>
    /// 查询信息存储体
    /// </summary>
    public class Query
    {
        /// <summary>
        /// 要更新的数据集
        /// </summary>
        public DataSet DataSet { get; set; }
        /// <summary>
        /// 要执行的SQL语句
        /// </summary>
        public string CommandText { get; set; }
        /// <summary>
        /// 查询参数集合
        /// </summary>
        public WDbParameter[] Parameters { get; set; }
        public Query()
        { }
        public Query(byte[] buffer)
        {
            buffer = buffer.Unzip();
            this.Fill(buffer);
        }
        public Query(string commandText, params WDbParameter[] parameters)
        {
            this.CommandText = commandText;
            this.Parameters = parameters;
        }

        public   byte[] ToArray()
        {
            byte[]result=null ;
            using (MemoryStream ms=new MemoryStream ())
            {
                using (BinaryWriter bw=new BinaryWriter(ms))
                {
                    bw.Write(this.CommandText);
                    bw.Write((int)this.Parameters .Length );
                    foreach (var parameter in this.Parameters )
                    {
                        var pBuffer = parameter.ToArray();
                        bw.Write(pBuffer.Length );
                        bw.Write(pBuffer);
                    }
                    if (this.DataSet ==null )
                    {
                        bw.Write(false );
                    }
                    else
                    {
                        bw.Write(true);
                        using (MemoryStream msDataSet=new MemoryStream ())
                        {
                            this.DataSet.WriteXml(msDataSet, XmlWriteMode.WriteSchema);
                            var dsBuffer = msDataSet.ToArray();
                            bw.Write(dsBuffer .Length );
                            bw.Write(dsBuffer,0,dsBuffer .Length );
                        }
                    }

                }
            }
            result = result.Zip();
            return result;
        }

        protected  void Fill(byte[] buffer)
        {
            using (MemoryStream ms=new MemoryStream (buffer))
            {
                using (BinaryReader br=new BinaryReader (ms))
                {
                    this.CommandText = br.ReadString();
                    var parameterCount = br.ReadInt32();
                    this.Parameters = new WDbParameter[parameterCount];
                    for (int i = 0; i < parameterCount ; i++)
                    {
                        int parameterBufferLength = br.ReadInt32();
                        byte[] parameterBuffer = br.ReadBytes(parameterBufferLength);
                        WDbParameter parameter = new WDbParameter(parameterBuffer);
                        this.Parameters[i] = parameter;
                    }
                    bool hasDataSet = br.ReadBoolean();
                    if (hasDataSet )
                    {
                        var dsLength = br.ReadInt32();
                        byte[] dsBuffer = br.ReadBytes(dsLength);
                        using (MemoryStream msDataSet=new MemoryStream (dsBuffer))
                        {
                            this.DataSet = new DataSet();
                            this.DataSet.ReadXml(msDataSet, XmlReadMode.ReadSchema);
                        }
                    }
                }
            }
        }
    }
}
